package main

import (
	"fmt"
	"sync"
	"time"
)

/*
channel 是 Go 中定义的一种类型，专门用来在多个 goroutine 之间通信的线程安全的数据结构。

可以在一个 goroutine 中向一个 channel 中发送数据，从另外一个 goroutine 中接收数据。

channel 类似队列，满足先进先出原则
*/
var wg sync.WaitGroup

func main() {

	/*
		发送和接收操作必须同时发生才能完成通信；
		如果只有一个 goroutine 发送，另一个还没准备好接收，则发送会阻塞；
		这种方式强调同步性。
	*/
	ch := make(chan int)

	/*
		带缓冲的channel
		可以缓存最多 N 个元素；
		发送操作不会立即阻塞，直到缓冲区满；
		接收操作也不会立即阻塞，直到缓冲区为空；
		更适合用于异步通信或解耦生产者与消费者的速度差异。
	*/
	//	ch := make(chan int, 6)

	go send(ch)
	go receive(ch)

	time.Sleep(time.Second)
}

/*
由于goroutine是异步执行，send方法的for循环非原子操作，所以会出现先打印"接收到: 2"再打印"send: 2"的情况
*/
func send(ch chan<- int) {
	for i := 0; i < 5; i++ {
		ch <- i
		fmt.Printf("send: %d\n", i)
	}
	close(ch)
}

func receive(ch <-chan int) {
	for i := range ch {
		fmt.Printf("接收到: %d\n", i)
	}
}
